package com.gap.dam.module.business.asset;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gap.dam.common.base.PageResultDTO;
import com.gap.dam.common.base.ResponseDTO;
import com.gap.dam.common.constant.JudgeEnum;
import com.gap.dam.module.business.asset.constant.AssetResponseCodeConst;
import com.gap.dam.module.business.asset.constant.AssetStatusEnum;
import com.gap.dam.module.business.asset.dao.AssetDao;
import com.gap.dam.module.business.asset.dao.AssetTagDao;
import com.gap.dam.module.business.asset.domain.dto.AssetAddDTO;
import com.gap.dam.module.business.asset.domain.dto.AssetQueryDTO;
import com.gap.dam.module.business.asset.domain.dto.AssetTagDTO;
import com.gap.dam.module.business.asset.domain.dto.AssetUpdateDTO;
import com.gap.dam.module.business.asset.domain.entity.AssetEntity;
import com.gap.dam.module.business.asset.domain.entity.AssetTagEntity;
import com.gap.dam.module.business.asset.domain.vo.AssetVO;
import com.gap.dam.module.business.tag.dao.TagDao;
import com.gap.dam.module.support.file.service.FileService;
import com.gap.dam.util.BeanUtil;
import com.gap.dam.util.PageUtil;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AssetService {

    @Autowired
    private AssetDao assetDao;

    @Autowired
    private TagDao tagDao;

    @Autowired
    private AssetTagDao assetTagDao;

    @Autowired
    private FileService fileService;

    /**
     * 分页查询Asset
     * @param assetQueryDTO
     * @return
     */
    public ResponseDTO<PageResultDTO<AssetVO>> queryAssetList(AssetQueryDTO assetQueryDTO) {
        Page page = PageUtil.convert2QueryPage(assetQueryDTO);
        List<AssetEntity> assetEntityList = assetDao.queryList(page, assetQueryDTO);
        return ResponseDTO.succData(PageUtil.convert2PageResult(page, assetEntityList, AssetVO.class));
    }

    /**
     * 查询所有Asset
     * @param assetQueryDTO
     * @return
     */
    public ResponseDTO<List<AssetVO>> queryAllAssetList(AssetQueryDTO assetQueryDTO) {
        List<AssetEntity> assetEntityList = assetDao.queryList(assetQueryDTO);
        List<AssetVO> asssetVOList = BeanUtil.copyList(assetEntityList, AssetVO.class);
        return ResponseDTO.succData(asssetVOList);
    }


    /**
     * 根据ID单个查询
     * @param id
     * @return
     */
    public ResponseDTO<AssetVO> queryById(Long id) {
        AssetEntity assetEntity = assetDao.selectById(id);
        AssetVO assetVO = BeanUtil.copy(assetEntity, AssetVO.class);
        return ResponseDTO.succData(assetVO);
    }

    /**
     * 添加Asset
     * @param assetAddDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<AssetVO> addAsset(AssetAddDTO assetAddDTO) {
        AssetEntity assetEntity = BeanUtil.copy(assetAddDTO, AssetEntity.class);
        assetDao.insert(assetEntity);
        AssetVO assetVO = BeanUtil.copy(assetEntity, AssetVO.class);
        return ResponseDTO.succData(assetVO);
    }


    /**
     * 根据ID删除
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> deleteById(Long id) {
        AssetEntity assetEntity = assetDao.selectById(id);
        if (null == assetEntity) {
            return ResponseDTO.wrap(AssetResponseCodeConst.ASSET_NOT_EXISTS);
        }

        assetEntity.setIsDelete((int)JudgeEnum.YES.getValue().longValue());
        assetDao.updateById(assetEntity);
        return ResponseDTO.succ();
    }

    /**
     * 根据ID列表删除
     * @param idList
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> deleteByIdList(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return ResponseDTO.wrap(AssetResponseCodeConst.ASSET_ID_LIST_EMPTY);
        }
        assetDao.batchDeleteAsset(idList, (int)JudgeEnum.YES.getValue().longValue());
        return ResponseDTO.succ();
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> updateAsset(AssetUpdateDTO assetUpdateDTO) {
        AssetEntity assetEntity = assetDao.selectById(assetUpdateDTO.getId());
        if (null == assetEntity) {
            return ResponseDTO.wrap(AssetResponseCodeConst.ASSET_NOT_EXISTS);
        }

        assetEntity = BeanUtil.copy(assetUpdateDTO, AssetEntity.class);
        assetDao.updateById(assetEntity);
        return ResponseDTO.succ();
    }

    /**
     * 根据id 下载文件
     *
     * @param id
     * @param request
     * @return
     */
    public ResponseEntity<byte[]> downLoadById(Long id, HttpServletRequest request) {
        AssetEntity assetEntity = assetDao.selectById(id);
        if (null == assetEntity) {
            throw new RuntimeException("Asset [" + id + "] not exists.");
        }
        if (null == assetEntity.getFileId()) {
            throw new RuntimeException("Asset [" + id + "] file not exists");
        }

        return fileService.downLoadById(assetEntity.getFileId(), request);
    }

    /**
     * 多文件下载
     * @param idList
     * @param request
     * @return
     */
    public ResponseEntity<byte[]> downloadMultiByIds(List<Long> idList, HttpServletRequest request) {
        List<AssetEntity> assetEntityList = assetDao.selectBatchIds(idList);
        if (assetEntityList.size() == 0) {
            throw new RuntimeException("cannot find Asset by id list " + idList.toString());
        }
        List<Long> fileIdList = assetEntityList.stream().map(AssetEntity::getFileId).collect(Collectors.toList());
        return fileService.downloadMutiByIdList(fileIdList, request);
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> batchUpdateCategory(List<Long> assetIdList, AssetUpdateDTO updateDTO) {
        assetDao.batchUpdateAsset(assetIdList, updateDTO);
        return ResponseDTO.succ();
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> batchUpdateTag(AssetTagDTO assetTagDTO) {
        if (assetTagDTO.getTagIdList().size() == 0)
            return ResponseDTO.wrap(AssetResponseCodeConst.ASSET_TAG_LIST_EMPTY);
        if (assetTagDTO.getAssetIdList().size() == 0)
            return ResponseDTO.wrap(AssetResponseCodeConst.ASSET_ID_LIST_EMPTY);

        // 批量删除原标签
        assetTagDao.batchDeleteTagsByAssetIdList(assetTagDTO.getAssetIdList());
        // 插入新标签
        for (Long assetId : assetTagDTO.getAssetIdList()) {
            List<AssetTagEntity> assetTagEntityList = Lists.newArrayList();
            for (Long tagId : assetTagDTO.getTagIdList()) {
                AssetTagEntity assetTagEntity = new AssetTagEntity();
                assetTagEntity.setAssetId(assetId);
                assetTagEntity.setTagId(tagId);
                assetTagEntityList.add(assetTagEntity);
            }
            assetTagDao.batchInsertAssetTags(assetTagEntityList);
        }
        return ResponseDTO.succ();
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> batchAuditAssets(List<Long> assetIdList) {
        if (assetIdList.size() == 0)
            return ResponseDTO.wrap(AssetResponseCodeConst.ASSET_ID_LIST_EMPTY);
        AssetUpdateDTO assetUpdateDTO = new AssetUpdateDTO();
        assetUpdateDTO.setPublishStatus(AssetStatusEnum.PUBLISH.getDesc());
        assetDao.batchUpdateAsset(assetIdList, assetUpdateDTO);
        return ResponseDTO.succ();
    }
}
